﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bzure.Common.Core;
using Bzure.Security.Principal;
using Bzure.Security.Permissions;

namespace System
{
    public static class PermissionExtensions
    {
        static DateTime LastPermissionChangeTime = DateTime.Now;
        public static DateTime GetLastPermissionChangeTime(this Public Public)
        {
            return LastPermissionChangeTime;
        }
        public static void UpdateLastPermissionChangeTime(this Public Public)
        {
            LastPermissionChangeTime = DateTime.Now;
        }
        /// <summary>
        /// 当前用户是否具有指定
        /// </summary>
        /// <param name="Me"></param>
        /// <param name="droit"></param>
        /// <returns></returns>
        public static bool Authorize(this Me Me, IDroit droit)
        {
            BzurePrincipal principal = Me.Principal as BzurePrincipal;
            if (principal == default(BzurePrincipal))
                return false;
            return principal.GetPermission().Authentication(droit);
        }
        /// <summary>
        /// 当前用户是否具有某项权限值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Me"></param>
        /// <param name="right">权限枚举值</param>
        /// <returns></returns>
        public static bool ContainDroit<T>(this Me Me, T right) where T : struct
        {
            Bzure.Security.Permissions.Droit droit = new Bzure.Security.Permissions.Droit(right.GetType().FullName);
            Bzure.Security.Permissions.AccessCode droitCode = new Bzure.Security.Permissions.AccessCode(Convert.ToInt32(right));
            droit.AddAccessCode(droitCode);
            return Me.Authorize(droit);
        }
        static Dictionary<string, Dictionary<Type, string>> GroupAuthTypes = new Dictionary<string, Dictionary<Type, string>>();
        public static IEnumerable<KeyValuePair<Type, string>> SystemRightTypes(this Public Public)
        {
            Dictionary<Type, string> dic = new Dictionary<Type, string>();
            foreach (Dictionary<Type, string> subDic in GroupAuthTypes.Values)
            {
                foreach (KeyValuePair<Type, string> pair in subDic)
                    dic[pair.Key] = pair.Value;
            }
            return dic;
        }
        public static IEnumerable<KeyValuePair<string, Dictionary<Type, string>>> GroupedSystemRightTypes(this Public Public)
        {
            return GroupAuthTypes;
        }
        public static string RightGroupName(Type type)
        {
            Attribute[] attributes = type.GetCustomAttributes(typeof(RightFlagAttribute), false) as Attribute[];
            RightFlagAttribute EnumStringsAttribute = attributes[0] as RightFlagAttribute;
            string name = EnumStringsAttribute.RightGroup;
            return name.IsNullOrEmpty() ? string.Empty : name;
        }
        public static string RightGroupName<EnumType>() where EnumType : struct
        {
            Attribute[] attributes = typeof(EnumType).GetCustomAttributes(typeof(RightFlagAttribute), false) as Attribute[];
            RightFlagAttribute EnumStringsAttribute = attributes[0] as RightFlagAttribute;
            string name = EnumStringsAttribute.RightGroup;
            return name.IsNullOrEmpty() ? string.Empty : name;
        }
        public static void RegisterSystemRightType<T>(this IApplicationStartContext StartContext) where T : struct
        {
            Actor.Public.AppendSystemRightType<T>();
        }
        public static void AppendSystemRightType<T>(this Public Public) where T : struct
        {
            string name = EnumHelper.EnumName<T>();
            string groupName = RightGroupName<T>();
            Dictionary<Type, string> dic = default(Dictionary<Type, string>);
            if (!GroupAuthTypes.TryGetValue(groupName, out dic))
            {
                dic = new Dictionary<Type, string>();
                GroupAuthTypes[groupName] = dic;
            }

            if (name.IsNotNullAndEmpty())
            {
                dic[typeof(T)] = name;
            }
        }
        public static BzurePrincipal AsBzurePrincipal(this Me Me)
        {
            if (Me.Principal.IsNull() || !(Me.Principal is BzurePrincipal))
                return default(BzurePrincipal);
            return Me.Principal as BzurePrincipal;
        }
    }
}
